unit Rails.View.Settings;

interface

uses
  System.Variants, IniFiles;

type
  TInputBank = (ibNone=0, ibMoney=1, ibAll=2);
  TRailsCase = (rcLower=0, rcNormal=1, rcUpper=2);

{$REGION 'TLocalSettings'}
  TLocalSettings = class
  private
    FUpperCase: TRailsCase;
    FInputBank: TInputBank;
    IniConfig: TIniFile;
  public
    constructor Create(User: String = '');
    destructor Destroy; override;
    procedure DefaultValues;
    property UpperCase: TRailsCase read FUpperCase write FUpperCase;
    property InputBank: TInputBank read FInputBank write FInputBank;
  end;
{$ENDREGION}

var
  LocalSettings: TLocalSettings;

implementation

uses
  RTTI, System.StrUtils, System.SysUtils, System.TypInfo;

{$REGION 'TLocalSettings'}
{ TLocalSettings }

constructor TLocalSettings.Create(User: String = '');
var
  Ctx: TRttiContext;
  Typ: TRttiType;
  Field: TRttiProperty;
  sUser: string;
begin
  if LocalSettings <> nil then
    FreeAndNil(LocalSettings);
  DefaultValues;

  Ctx := TRttiContext.Create;
  Typ := Ctx.GetType(Self.ClassType);
  sUser := IfThen(User<>EmptyStr, sUser+'\LocalSettings.ini', 'LocalSettings.ini');
  IniConfig := TIniFile.Create(ExtractFilePath(ParamStr(0))+sUser);
  for Field in Typ.GetProperties do
  begin
    if IniConfig.ValueExists(Self.ClassName, Field.Name) then
    begin
      case Field.PropertyType.TypeKind of
        tkEnumeration : Field.SetValue(Self, TValue.FromOrdinal(Field.PropertyType.Handle, IniConfig.ReadInteger(Self.ClassName, Field.Name, 0)));
        tkInteger, tkFloat, tkInt64: Field.SetValue(Self, IniConfig.ReadInteger(Self.ClassName, Field.Name, 0));
        tkString, tkChar, tkWChar, tkLString, tkWString, tkVariant, tkUString: Field.SetValue(Self, IniConfig.ReadString(Self.ClassName, Field.Name, ''));
      end;
    end;
  end;
end;

procedure TLocalSettings.DefaultValues;
begin
  UpperCase := rcNormal;
  InputBank := ibMoney;
end;

destructor TLocalSettings.Destroy;
var
  Ctx: TRttiContext;
  Typ: TRttiType;
  Field: TRttiProperty;
begin
  Ctx := TRttiContext.Create;
  Typ := Ctx.GetType(Self.ClassType);
  for Field in Typ.GetProperties do
  begin
    case Field.PropertyType.TypeKind of
      tkEnumeration: IniConfig.WriteInteger(Self.ClassName, Field.Name, Field.GetValue(Self).AsOrdinal);
      tkFloat: IniConfig.WriteFloat(Self.ClassName, Field.Name, Field.GetValue(Self).AsExtended);
      tkInteger, tkInt64: IniConfig.WriteInteger(Self.ClassName, Field.Name, Field.GetValue(Self).AsInt64);
      tkString, tkChar, tkWChar, tkLString, tkWString, tkVariant, tkUString: IniConfig.WriteString(Self.ClassName, Field.Name, Field.GetValue(Self).ToString);
    end;
  end;
  FreeAndNil(IniConfig);
  inherited;
end;
{$ENDREGION}

initialization
  LocalSettings := TLocalSettings.Create;

finalization
  FreeAndNil(LocalSettings);

end.
